# @Time : 2021/4/7 10:41
# @Author : Fioman 
# @Phone : 13149920693
"""
mogodb数据库的一些API,主要是封装了数据库的操作的一些API
"""
import datetime
import os
import threading
import time

import pymongo

from db_tools.db_data_manager import dump_data, import_data
from settings import DATABASE_NAME, CALC_ARGS_TXT_PATH
from tools.common_tools import get_time_now_string
from tools.hd_logger import HdLogger
from tools.save_image_to_device import open_database_dump_dir, open_database_import_dir


def synchronized(func):
    """
    线程安全的装饰器,加一个线程锁
    :param func:
    :return:
    """
    func.__lock__ = threading.Lock()

    def lock_func(*args, **kwargs):
        with func.__lock__:
            return func(*args, **kwargs)

    return lock_func


class DbHandler(object):
    url = "mongodb://localhost:27017/"
    paramsDbName = DATABASE_NAME
    __dbHandler__ = None
    __initFlag__ = False

    @synchronized
    def __new__(cls, *args, **kwargs):
        if cls.__dbHandler__ is None:
            cls.__dbHandler__ = object.__new__(cls)
        return cls.__dbHandler__

    def __init__(self):
        if not DbHandler.__initFlag__:
            print("DbHandler.__init__() 进行初始化")
            DbHandler.__initFlag__ = True
            self.eapProdDownloadTable = "productionInfoDownLoad"
            self.lotCommandDownloadTable = "lotCommandDownloadTable"
            self.cimMessageTable = "cimMessageTable"  # 远程讯息历史记录里查询,也是按照插入时间
            self.logger = HdLogger()
            self.client = pymongo.MongoClient(self.url)
            self.paramsDb = self.client[self.paramsDbName]
            # 统计所有的数据库表格
            collist = self.paramsDb.list_collection_names()

            self.eap_user_table = "eap_user_table"
            if self.eap_user_table not in collist:
                data = {
                    "key": "1",
                    "clock_type": "ClockIn",
                    "user_id": "NoBody",
                    "user_name": "NoBody",
                    "dept_id": "NoBody",
                    "shift_id": "NoBody",
                    "nick_name": "NoBody"
                }
                self.insert_data(self.eap_user_table, data)

            self.orderTable = "order"
            if self.orderTable not in collist:
                data = {
                    "key": 1,
                    "width": 600,
                    "height": 600,
                    "isFirstTime": False,
                    "jointNumber": "2",
                    "isBroken": "否"
                }
                self.insert_data(self.orderTable, data)

            self.offlineZmcParamsTable = "offlineZmcParams"
            if self.offlineZmcParamsTable not in collist:
                data = {
                    "key": "1"
                }
                self.insert_data(self.offlineZmcParamsTable, data)

            tableName = "camZmcParams"
            if tableName not in collist:
                data = {
                    "key": "1"
                }
                self.insert_data(tableName, data)

            self.cbjZmcParamsTable = "cbjZmcParams"
            if self.cbjZmcParamsTable not in collist:
                data = {
                    "key": "1"
                }
                self.insert_data(self.cbjZmcParamsTable, data)

            tableName = "smallCutterZmcParams"
            if tableName not in collist:
                data = {
                    "key": "1"
                }
                self.insert_data(tableName, data)

            tableName = "bigCutterZmcParams"
            if tableName not in collist:
                data = {
                    "key": "1"
                }
                self.insert_data(tableName, data)
            self.configParamsTable = "configParams"
            if self.configParamsTable not in collist:
                data = {
                    "key": "1",
                    "cameraWidth": 2048,
                    "cameraHeight": 4000,
                    "heightWidthRatio": 1,
                    "mm2pix": 1,
                    "middleJointPos": 0,
                    "sensorPos": 0,
                    "tablePosStart": 0,
                    "tablePosEnd": 0,
                    "tableValUsed": 15,
                    "sensorValUsed": 15,
                    "calcArgsZj01": {
                        "1": [[2], 10, 11, 8, 15, [60, 40, 100, 120, 150, 200], 0.2],
                        "2": [[15, 120], 10, 11, 8, 20, [80, 40, 20], 0.4],
                        "3": [[5], 17, 11, 8, 20, [100, 80, 60, 50], 0.5],
                    },
                    "sizeScale": 1.25,  # 显示800个mm,然后实际的高宽比,是像素比除以这个数.
                    "longCropperLimit": 100  # 是否是长铜箔,停板
                }
                self.insert_data(self.configParamsTable, data)

            self.workingInfoTable = "workingInfo"
            if self.workingInfoTable not in collist:
                data = {
                    "key": "1",
                    "loginSuccess": False,
                    "camZmcIndex": 0,
                    "cbjZmcIndex": 0,
                    "cutterZmcIndex": 0,
                    "tableUsed": 0,
                    "cutAreas": 0,
                    "cutAmounts": 0,
                    "cutId": 0,
                    "indexMax": 10000,
                    "knifeMax": 40000,
                    "knifeUsed": 0,
                    "tableUsedInit": get_time_now_string(),
                    "tableUsedDays": 0,
                }
                self.insert_data(self.workingInfoTable, data)
            else:
                query = {
                    "key": "1"
                }
                newValues = {
                    "$set": {
                        "loginSuccess": False
                    }
                }
                self.update_data(self.workingInfoTable, query, newValues)

            tableName = "userinfo"
            if tableName not in collist:
                data = {

                }
                self.insert_data(tableName, data)

            self.lineCamCheckThres = "lineCamCheckThres"
            if self.lineCamCheckThres not in collist:
                data = {
                    "key": "1",
                    "totalHeightMax": 1350,
                    "totalHeightMin": 1280,
                    "calcThresBig": 20,
                    "calcThresSmall": 10,
                    "innerToEdgeThres": 5,
                    "firstBoardErrorThres": 2.5,
                    "secondBoardErrorThres": 15,
                    "totalBoardErrorThres": 20
                }
                self.insert_data(self.lineCamCheckThres, data)

            self.cutterCamCheckThresBig = "cutterCamCheckThresBig"
            if self.cutterCamCheckThresBig not in collist:
                data = {
                    "key": "1",
                    "beginAngleThresBig": 0.2,
                    "beginAngleOffsetBig": 0,
                    "cutterMoveOffsetBig": 0,
                    "finalFirstBoardThresBig": 2.5,
                    "finalSecondBoardThresBig": 12,
                    "finalTotalBoardThresBig": 18,
                    "finalFrontAngleBig": 1,
                    "finalBackAngleBig": 2,
                    "finalFoldThresBig": 8,  # 终检大铡刀叠板阈值
                }
                self.insert_data(self.cutterCamCheckThresBig, data)

            self.cutterCamCheckThresSmall = "cutterCamCheckThresSmall"
            if self.cutterCamCheckThresSmall not in collist:
                data = {
                    "key": "1",
                    "beginAngleThresSmall": 0.2,
                    "beginAngleOffsetSmall": 0,
                    "cutterMoveOffsetSmall": 0,
                    "finalFirstBoardThresSmall": 2.5,
                    "finalSecondBoardThresSmall": 12,
                    "finalTotalBoardThresSmall": 18,
                    "finalFrontAngleSmall": 1,
                    "finalBackAngleSmall": 2,
                    "finalFoldThresSmall": 8,  # 终检小铡刀叠板阈值
                    "twoCutterAngleOffset": 0,  # 两台铡刀的角度
                }
                self.insert_data(self.cutterCamCheckThresSmall, data)

            self.knifeCutParams = "knifeCutParams"
            if self.knifeCutParams not in collist:
                data = {
                    "key": "1",
                    "speedLev1": 900,
                    "speedLev2": 900,
                    "speedLev3": 900,
                    "speedLev4": 900,
                    "speedLev5": 600,
                    "firstCutRate": 0.8,
                    "toolCutSpped": 600,
                    "cutDeep": 32,
                    "knifeAngleOffset": 0,  # 如果是0,就从底层获取这个值
                }
                self.insert_data(self.knifeCutParams, data)

            self.transMtxTable = "transMtx"
            if self.transMtxTable not in collist:
                data = {
                    "key": "1",
                    "mtx": [
                        [1, 0, 1],
                        [0, 1, 0]
                    ]
                }
                self.insert_data(self.transMtxTable, data)

            self.capfileTable = "capfileData"
            if self.capfileTable not in collist:
                data = {
                    "key": "1",
                    "capfileData": [],
                    "xMin": 0,
                    "yMin": 0,
                    "xInterval": 0,
                    "yInterval": 0,
                    "xNums": 0,
                    "yNums": 0
                }
                self.insert_data(self.capfileTable, data)

            self.imageJointParamsTable = "imageJointParams"
            if self.imageJointParamsTable not in collist:
                data = {
                    "key": "1",
                    "leftCamStartOffset": 0,
                    "leftCamEndOffset": 0,
                    "rightCamStartOffset": 0,
                    "rightCamEndOffset": 0,
                    "leftCamHOffset": 0,
                }
                self.insert_data(self.imageJointParamsTable, data)

            self.light1ParamsTalbeBig = "light1ParamsBig"
            if self.light1ParamsTalbeBig not in collist:
                data = {
                    "key": "1",
                    "xStart": 0,
                    "xEnd": 0,
                    "yStart": 0,
                    "yEnd": 0,
                    "pos1Pix": 400,
                    "pos1Mm": 400,
                    "pos2Pix": 600,
                    "pos2Mm": 600,
                    "mmToPix": 1,
                    "lightBtween12": 300
                }
                self.insert_data(self.light1ParamsTalbeBig, data)

            self.light2ParamsTableBig = "light2ParamsBig"
            if self.light2ParamsTableBig not in collist:
                data = {
                    "key": "1",
                    "xStart": 0,
                    "xEnd": 0,
                    "yStart": 0,
                    "yEnd": 0,
                    "pos1Pix": 400,
                    "pos1Mm": 400,
                    "pos2Pix": 600,
                    "pos2Mm": 600,
                    "mmToPix": 1,
                    "lightBtween12": 300
                }
                self.insert_data(self.light2ParamsTableBig, data)

            self.light3ParamsTableBig = "light3ParamsBig"
            if self.light3ParamsTableBig not in collist:
                data = {
                    "key": "1",
                    "xStart": 0,
                    "xEnd": 0,
                    "yStart": 0,
                    "yEnd": 0,
                    "pos1Pix": 400,
                    "pos1Mm": 400,
                    "pos2Pix": 600,
                    "pos2Mm": 600,
                    "mmToPix": 1,
                    "lightBtween34": 300
                }
                self.insert_data(self.light3ParamsTableBig, data)

            self.light4ParamsTableBig = "light4ParamsBig"
            if self.light4ParamsTableBig not in collist:
                data = {
                    "key": "1",
                    "xStart": 0,
                    "xEnd": 0,
                    "yStart": 0,
                    "yEnd": 0,
                    "pos1Pix": 400,
                    "pos1Mm": 400,
                    "pos2Pix": 600,
                    "pos2Mm": 600,
                    "mmToPix": 1,
                    "lightBtween34": 300
                }
                self.insert_data(self.light4ParamsTableBig, data)
            self.light1ParamsTalbeSmall = "light1ParamsSmall"
            if self.light1ParamsTalbeSmall not in collist:
                data = {
                    "key": "1",
                    "xStart": 0,
                    "xEnd": 0,
                    "yStart": 0,
                    "yEnd": 0,
                    "pos1Pix": 400,
                    "pos1Mm": 400,
                    "pos2Pix": 600,
                    "pos2Mm": 600,
                    "mmToPix": 1,
                    "lightBtween12": 300
                }
                self.insert_data(self.light1ParamsTalbeSmall, data)

            self.light2ParamsTalbeSmall = "light2ParamsSmall"
            if self.light2ParamsTalbeSmall not in collist:
                data = {
                    "key": "1",
                    "xStart": 0,
                    "xEnd": 0,
                    "yStart": 0,
                    "yEnd": 0,
                    "pos1Pix": 400,
                    "pos1Mm": 400,
                    "pos2Pix": 600,
                    "pos2Mm": 600,
                    "mmToPix": 1,
                    "lightBtween12": 300
                }
                self.insert_data(self.light2ParamsTalbeSmall, data)

            self.light3ParamsTalbeSmall = "light3ParamsSmall"
            if self.light3ParamsTalbeSmall not in collist:
                data = {
                    "key": "1",
                    "xStart": 0,
                    "xEnd": 0,
                    "yStart": 0,
                    "yEnd": 0,
                    "pos1Pix": 400,
                    "pos1Mm": 400,
                    "pos2Pix": 600,
                    "pos2Mm": 600,
                    "mmToPix": 1,
                    "lightBtween34": 300
                }
                self.insert_data(self.light3ParamsTalbeSmall, data)

            self.light4ParamsTalbeSmall = "light4ParamsSmall"
            if self.light4ParamsTalbeSmall not in collist:
                data = {
                    "key": "1",
                    "xStart": 0,
                    "xEnd": 0,
                    "yStart": 0,
                    "yEnd": 0,
                    "pos1Pix": 400,
                    "pos1Mm": 400,
                    "pos2Pix": 600,
                    "pos2Mm": 600,
                    "mmToPix": 1,
                    "lightBtween34": 300
                }
                self.insert_data(self.light4ParamsTalbeSmall, data)

            self.mainAlarmInfoTable = "mainAlarmInfo"
            if self.mainAlarmInfoTable not in collist:
                data = {
                    "key": "1",
                    "mainAlarmInfo": {
                        "3000": "上料 轴0报警",
                        "3001": "上料 轴1报警",
                        "3002": "上料 轴2报警",
                        "3003": "上料 轴3报警",
                        "3009": "上料 机械手急停报警",
                        "3010": "上料 门开关故障报警",
                        "3013": "上料 吸盘真空故障报警",
                        "3016": "上料 门禁1故障报警",
                        "3017": "上料 门禁2故障报警",
                        "3018": "上料 门禁3故障报警",
                        "3019": "上料 门禁4故障报警",
                        "3020": "上料 拍照故障报警",
                        "3028": "上料 等待检测结果超时报警",
                        "3031": "上料 按钮急停报警",

                        "3050": "裁切机 轴0报警",
                        "3051": "裁切机 轴1报警",
                        "3052": "裁切机 轴2报警",
                        "3053": "裁切机 轴3报警",
                        "3054": "裁切机 圆刀报警",
                        "3059": "裁切机 夹台布气缸下压故障报警",
                        "3060": "裁切机 夹台布气缸上升故障报警",
                        "3061": "裁切机 破真空气缸打开故障报警",
                        "3062": "裁切机 破真空气缸关闭故障报警",
                        "3063": "裁切机 真空吸附不足异常报警",
                        "3065": "裁切机 光栅报警",
                        "3078": "裁切机 等待裁切机数据超时报警",
                        "3079": "裁切机 等待铡刀数据超时报警",
                        "3081": "裁切机 按钮急停报警",

                        "3100": "大铡刀 轴0报警",
                        "3101": "大铡刀 轴1报警",
                        "3102": "大铡刀 轴2报警",
                        "3103": "大铡刀 轴3报警",
                        "3104": "大铡刀 轴4报警",
                        "3110": "大铡刀 门开关报警",
                        "3111": "大铡刀 压板气缸上报警",
                        "3112": "大铡刀 压板气缸下报警",
                        "3113": "大铡刀 吸盘真空故障",
                        "3114": "大铡刀 旋转轴找零失败报警",
                        "3115": "大铡刀 铡刀找零失败报警",
                        "3116": "大铡刀 门禁 1 报警",
                        "3117": "大铡刀 门禁 2 报警",
                        "3120": "大铡刀 前端视觉检测报警",
                        "3121": "大铡刀 后段视觉检测报警",
                        "3122": "大铡刀 进料口传感器被挡 报警",
                        "3123": "大铡刀 拍照传感器被挡 报警",
                        "3124": "大铡刀 出料口传感器被挡 报警",
                        "3125": "大铡刀 进料超时 报警",
                        "3126": "大铡刀 拍照超时 报警",
                        "3127": "大铡刀 出料超时 报警",
                        "3128": "大铡刀 等待检测结果超时 报警",
                        "3130": "大铡刀 缓存线上有板 报警",
                        "3131": "大铡刀  按钮急停",

                        "3150": "小铡刀 轴0报警",
                        "3151": "小铡刀 轴1报警",
                        "3152": "小铡刀 轴2报警",
                        "3153": "小铡刀 轴3报警",
                        "3154": "小铡刀 轴4报警",
                        "3155": "小铡刀 轴5报警",
                        "3160": "小铡刀 门开关报警",
                        "3161": "小铡刀 压板气缸上报警",
                        "3162": "小铡刀 压板气缸下报警",
                        "3163": "小铡刀 吸盘真空故障",
                        "3164": "小铡刀 旋转轴找零失败报警",
                        "3165": "小铡刀 铡刀找零失败报警",
                        "3166": "小铡刀 门禁 1 报警",
                        "3167": "小铡刀 门禁 2 报警",
                        "3170": "小铡刀 前端视觉检测报警",
                        "3171": "小铡刀 后段视觉检测报警",
                        "3173": "小铡刀 拍照传感器被挡 报警",
                        "3174": "小铡刀 出料口传感器被挡 报警",
                        "3177": "小铡刀 出料超时 报警",
                        "3178": "小铡刀 等待检测结果超时 报警",
                        "3180": "小铡刀 缓存线上有板 报警",
                        "3181": "小铡刀  按钮急停",

                    }
                }
                self.insert_data(self.mainAlarmInfoTable, data)
            self.mainAlarmInfoUSTable = "mainAlarmInfoUS"
            if self.mainAlarmInfoUSTable not in collist:
                data = {
                    "key": "1",
                    "mainAlarmInfo": {
                        "3000": "Feeding shaft 0 alarm ",
                        "3001": "Feeding shaft 1 alarm ",
                        "3002": "Feeding shaft 2 alarm ",
                        "3003": "Feeding shaft 3 alarm ",
                        "3009": "Feeding manipulator emergency stop alarm ",
                        "3010": "Feeding door switch failure alarm ",
                        "3013": "Feeding sucker vacuum failure alarm ",
                        "3016": "Feeding access guard 1 failure alarm ",
                        "3017": "Feeding access control 2 failure alarm ",
                        "3018": "Feeding access control 3 failure alarm ",
                        "3019": "Feeding access control 4 fault alarm ",
                        "3020": "feeding photo fault alarm ",
                        "3028": "Feeding waiting for test result timeout alarm ",
                        "3031": "Feeding button emergency stop alarm ",

                        "3050": "Cutting machine shaft 0 alarm ",
                        "3051": "Cutting machine shaft 1 alarm ",
                        "3052": "Cutting machine shaft 2 alarm ",
                        "3053": "Cutting machine shaft 3 alarm ",
                        "3054": "Cutting machine round knife alarm ",
                        "3059": "Cutting machine clip tablecloth cylinder pressure failure alarm ",
                        "3060": "Cutting machine clip tablecloth cylinder rising fault alarm ",
                        "3061": "Cutting machine broken vacuum cylinder open fault alarm ",
                        "3062": "Cutting machine broken vacuum cylinder closing failure alarm ",
                        "3063": "Cutting machine vacuum adsorption insufficient abnormal alarm ",
                        "3065": "Cutting machine grating alarm ",
                        "3078": "Cutting machine waiting for cutting machine data timeout alarm ",
                        "3079": "Cutter waits for guillotine data timeout alarm ",
                        "3081": "Cutting machine button emergency stop alarm ",

                        "3100": "Big Split board machine axis 0 Alarms ",
                        "3101": "Big Split board machine Shaft 1 Alarms ",
                        "3102": "Big Split board machine Shaft 2 Alarms ",
                        "3103": "Big Split board machine Shaft 3 Alarms ",
                        "3104": "Big Split board machine Shaft 4 Alarms ",
                        "3110": "Big Split board machine Door switch Alarm ",
                        "3111": "Big Split board machine Pressure plate cylinder top sensor sensing timeout alarm ",
                        "3112": "Big Split board machine Pressure plate cylinder bottom sensor sensing timeout alarm ",
                        "3113": "Big Split board machine Suction cup vacuum fault alarm ",
                        "3114": "Big Split board machine Rotation axis return to origin failure alarm ",
                        "3115": "Big Split board machine Sickle cannot return to origin alarm.",
                        "3116": "Big Split board machine Access Control 1 failure Alarm ",
                        "3117": "Big Split board machine Access Control 2 failure Alarm ",
                        "3120": "Big Split board machine Front-end Visual Detection Alarm ",
                        "3121": "Big Split board machine Back-end visual detection alarm",
                        "3122": "Big Split board machine feed port sensor blocked alarm ",
                        "3123": "Big Split board machine Camera sensor blocked alarm ",
                        "3124": "Big Split board machine The discharge port sensor is blocked and alarm ",
                        "3125": "Big Split board machine feeding timeout alarm ",
                        "3126": "Big Split board machine Image Timeout Alarm ",
                        "3127": "Big Split board machine Outfeed timeout alarm",
                        "3128": "Big Split board machine Waiting for test result timeout alarm",
                        "3130": "Big Split board machine There is a board alarm on the temporary storage platform. ",
                        "3131": "Big Split board machine button stops abruptly ",

                        "3150": "Small Split board machine axis 0 Alarms ",
                        "3151": "Small Split board machine Shaft 1 Alarms ",
                        "3152": "Small Split board machine Shaft 2 Alarms ",
                        "3153": "Small Split board machine Shaft 3 Alarms ",
                        "3154": "Small Split board machine Shaft 4 Alarms ",
                        "3155": "Small Split board machine Shaft 5 Alarms ",
                        "3160": "Small Split board machine Door switch Alarm ",
                        "3161": "Small Split board machine Pressure plate cylinder top sensor sensing timeout alarm ",
                        "3162": "Small Split board machine Pressure plate cylinder bottom sensor sensing timeout alarm ",
                        "3163": "Small Split board machine Suction cup vacuum fault alarm ",
                        "3164": "Small Split board machine Rotation axis return to origin failure alarm ",
                        "3165": "Small Split board machine Sickle cannot return to origin alarm.",
                        "3166": "Small Split board machine Access Control 1 failure Alarm ",
                        "3167": "Small Split board machine Access Control 2 failure Alarm ",
                        "3170": "Small Split board machine Front-end Visual Detection Alarm ",
                        "3171": "Small Split board machine Back-end visual detection alarm ",
                        "3173": "Small Split board machine Camera sensor blocked alarm ",
                        "3174": "Small Split board machine The discharge port sensor is blocked and alarm ",
                        "3177": "Small Split board machine Outfeed timeout alarm",
                        "3178": "Small Split board machine Waiting for test result timeout alarm ",
                        "3180": "Small Split board machine There is a board alarm on the temporary storage platform. ",
                        "3181": "Small Split board machine button stops abruptly ",
                    }
                }
                self.insert_data(self.mainAlarmInfoUSTable, data)

            self.offlineAlarmInfoTable = "offlineAlarmInfo"
            if self.offlineAlarmInfoTable not in collist:
                data = {
                    "key": "1",
                    "offlineAlarmInfo": {
                        "500": "轴0报警",
                        "501": "轴1报警",
                        "507": "小车高度不够",
                        "508": "小车没有物料",
                        "509": "小车没有到位",
                        "510": "门开关故障",
                        "511": "门口对射报警",
                        "513": "吸盘真空故障"
                    }
                }
                self.insert_data(self.offlineAlarmInfoTable, data)

            self.produceAmountRecordTable = "prodcueAmountRecord"
            if self.produceAmountRecordTable not in collist:
                data = {
                    "key": "1",
                    "recordYear": datetime.datetime.now().year,
                    "1": 0,
                    "2": 0,
                    "3": 0,
                    "4": 0,
                    "5": 0,
                    "6": 0,
                    "7": 0,
                    "8": 0,
                    "9": 0,
                    "10": 0,
                    "11": 0,
                    "12": 0,
                    "dayAmount": {

                    }
                }
                self.insert_data(self.produceAmountRecordTable, data)

            self.eap_config_params = "eap_config_params"
            if self.eap_config_params not in collist:
                data = {
                    "key": "1",
                    "eqp_id": "hd01",
                    "eqp_ip": "127.0.0.1",
                    "eqp_port": "8026",
                    "eap_ip": "127.0.0.1",
                    "eap_port": "8026",
                    "ask_duration": "1800",
                    "cim_mode": "Local",
                    "auto_mode": "自动模式"
                }
                self.insert_data(self.eap_config_params, data)

            self.alarmReportToEapTable = "alarmReportToEap"
            if self.alarmReportToEapTable not in collist:
                data = {
                    "key": "1",
                    "camZmcConnError": "0",
                    "cbjZmcConnError": "0",
                    "cutterZmcConnError": "0",
                    "camZmcRs": "0",
                    "cbjZmcRs": "0",
                    "cutterZmcRs": "0",
                    "cameraError": "0"
                }
                self.insert_data(self.alarmReportToEapTable, data)

            self.deviceStateToEapTable = "deviceStateToEap"
            if self.deviceStateToEapTable not in collist:
                data = {
                    "key": "1",
                    "camZmcStates": "0",
                    "cbjZmcStates": "0",
                    "bigCutterZmcStates": "0",
                    "smallCutterZmcStates": "0",
                }
                self.insert_data(self.deviceStateToEapTable, data)

            self.camZmc_IOInfo = "camZmcIOInfo"
            if self.camZmc_IOInfo not in collist:
                data = {
                    "key": 1,
                    "0": "进料检测",
                    "1": "拍照触发",
                    "2": "终点检测",
                    "3": "气源压力检测",
                    "4": "急停",
                    "5": "复位",
                    "6": "负压开关信号（备用）",
                    "7": "横梁左极限（备用）",
                    "8": "横梁右极限（备用）",
                    "9": "横梁零点（备用）",
                    "10": "Z轴上极限（备用）",
                    "11": "Z轴下极限（备用）",
                    "12": "Z轴零点（备用）",
                    "13": "门禁1（备用）",
                    "14": "门禁2（备用）",
                    "15": "门禁3（备用）",
                    "16": "门禁4（备用）",
                    "24": "横梁轴电机报警",
                    "25": "上下轴电机报警",
                    "26": "皮带电机报警",
                    "54": "上料完成信号/回流线允许传送",
                    "55": "机械手抓板完成",
                    "56": "机械手放板完成",
                    "57": "机械手急停输出",
                    "58": "机械手报警灯输出",
                    "59": "机械手抓板失败",
                    "60": "机械手暂停",
                    "61": "机械手使能输出",
                    "62": "机械手回到工作零点",
                }
                self.insert_data(self.camZmc_IOInfo, data)
            self.camZmcOPInfo = "camZmcOPInfo"
            if self.camZmcOPInfo not in collist:
                data = {
                    "key": 1,
                    "0": "蜂鸣器",
                    "1": "机械手急停",
                    "2": "伺服报警清除",
                    "3": "拍照传感器屏蔽",
                    "4": "允许来料信号 KA2",
                    "6": "光源打开",
                    "14": "皮带使能",
                }
                self.insert_data(self.camZmcOPInfo, data)

            self.cbjZmc_IOInfo = "cbjZmcIOInfo"
            if self.cbjZmc_IOInfo not in collist:
                data = {
                    "key": 1,
                    "0": "X轴原点",
                    "1": "Y轴原点",
                    "2": "Z轴原点",
                    "3": "R轴原点",
                    "4": "圆刀报警",
                    "5": "X轴到位信号",
                    "6": "Y轴到位信号",
                    "7": "复位 ",
                    "8": "急停 ",
                    "9": "光栅报警（备用）",
                    "10": "夹台布气缸上限位",
                    "11": "夹台布气缸下限位",
                    "12": "真空破坏气缸左限位",
                    "13": "真空破坏气缸右限位",
                    "14": "料框到位信号（备用）",

                    "24": "X电机报警信号",
                    "25": "Y电机报警信号",
                    "26": "Z电机报警信号",
                    "27": "R电机报警信号",
                }
                self.insert_data(self.cbjZmc_IOInfo, data)
            self.cbjZmcOPInfo = "cbjZmcOPInfo"
            if self.cbjZmcOPInfo not in collist:
                data = {
                    "key": 1,
                    "0": "电机报警清除",
                    "1": "真空破坏",
                    "2": "设备报警",
                    "8": "真空泵启动 ",
                    "9": "振动刀启动 ",

                    "10": "夹台布气缸",

                    "12": "X轴使能",
                    "13": "Y轴使能",
                    "14": "Z轴使能",
                    "15": "R轴使能",
                }
                self.insert_data(self.cbjZmcOPInfo, data)

            self.bigCutterIOInfo = "bigCutterIOInfo"
            if self.bigCutterIOInfo not in collist:
                data = {
                    "key": 1,
                    "0": "进料检测",
                    "1": "减速检测-拍照传感器1",
                    "2": "铡刀原点",
                    "3": "出料检测1",
                    "4": "Z轴原点",
                    "5": "Z轴上极限",
                    "6": "Z轴下极限",
                    "7": "R轴原点",
                    "8": "负压传感器",
                    "9": "急停 ",
                    "10": "复位",
                    "11": "压板气缸上限位",
                    "12": "压板气缸下限位",
                    "13": "门禁1",
                    "14": "门禁2",
                    "15": "风刀原点",
                    "16": "气源压力开关（备用）",
                    "17": "出料检测2",
                    "18": "铡刀备用原点",

                    "20": "允许出板信号（备用）",
                    "21": "缓存线进料传感器（备用）",
                    "22": "缓存线出料传感器（备用）",
                    "23": "拍照传感器2",

                    "40": "进料皮带电机报警",
                    "41": "出料皮带电机报警",
                    "42": "上下轴电机报警",
                    "43": "旋转电机报警",
                    "44": "铡刀电机报警",
                    "45": "风刀电机报警",
                }
                self.insert_data(self.bigCutterIOInfo, data)

            self.bigCutterOPInfo = "bigCutterOPInfo"
            if self.bigCutterOPInfo not in collist:
                data = {
                    "key": 1,
                    "0": "真空控制",
                    "1": "三色灯——红灯",
                    "2": "三色灯——黄灯",
                    "3": "三色灯——绿灯",
                    "4": "蜂鸣器",
                    "5": "真空破坏",
                    "6": "风刀吹气",
                    "7": "吹气控制2",
                    "8": "真空泵控制 KA2（备用）",
                    "9": "前段光源控制 KA3 ",
                    "10": "后段光源控制 KA4",
                    "11": "Z轴刹车",
                    "12": "轴报警清除",
                    "13": "压板气缸下",
                    "14": "缓存传送带启动（备用）",
                    "15": "激光照明启动",
                    "16": "进料皮带电机使能",
                    "17": "进料皮带电机报警清除",
                    "18": "出料皮带电机使能",
                    "19": "出料皮带电机报警清除",
                    "20": "上下轴电机使能",
                    "21": "上下轴电机报警清除",
                    "22": "旋转电机使能",
                    "23": "旋转电机报警清除",
                    "24": "铡刀电机使能",
                    "25": "铡刀电机报警清除",
                }
                self.insert_data(self.bigCutterOPInfo, data)

            self.smallCutterIOInfo = "smallCutterIOInfo"
            if self.smallCutterIOInfo not in collist:
                data = {
                    "key": 1,
                    "0": "拍照传感器1",
                    "1": "拍照传感器2",
                    "2": "铡刀原点",
                    "3": "出料检测1",
                    "4": "Z轴原点",
                    "5": "Z轴上极限",
                    "6": "Z轴下极限",
                    "7": "R轴原点",
                    "8": "负压传感器",
                    "9": "急停 ",
                    "10": "复位",
                    "11": "压板气缸上限位",
                    "12": "压板气缸下限位",
                    "13": "门禁1",
                    "14": "门禁2",
                    "15": "铡刀备用原点",
                    "16": "气源压力开关（备用）",
                    "17": "横梁原点",
                    "18": "横梁左极限",
                    "19": "横梁右极限",
                    "20": "允许出板信号",
                    "21": "缓存线进料传感器",
                    "22": "缓存线出料传感器",
                    "23": "出料检测2",

                    "40": "进料皮带电机报警",
                    "41": "出料皮带电机报警",
                    "42": "上下轴电机报警",
                    "43": "旋转电机报警",
                    "44": "铡刀电机报警",
                    "45": "横梁电机报警",
                }
                self.insert_data(self.smallCutterIOInfo, data)

            self.smallCutterIOInfo = "smallCutterOPInfo"
            if self.smallCutterIOInfo not in collist:
                data = {
                    "key": 1,
                    "0": "真空控制",
                    "1": "三色灯——红灯",
                    "2": "三色灯——黄灯",
                    "3": "三色灯——绿灯",
                    "4": "蜂鸣器",
                    "5": "真空破坏",
                    "6": "风刀吹气",
                    "7": "吹气控制2",
                    "8": "真空泵控制 KA2（备用）",
                    "9": "前段光源控制 KA3 ",
                    "10": "后段光源控制 KA4",
                    "11": "Z轴刹车",
                    "12": "轴报警清除",
                    "13": "压板气缸下",
                    "14": "缓存传送带启动（备用）",
                    "15": "激光照明启动",
                    "16": "进料皮带电机使能",
                    "17": "进料皮带电机报警清除",
                    "18": "出料皮带电机使能",
                    "19": "出料皮带电机报警清除",
                    "20": "上下轴电机使能",
                    "21": "上下轴电机报警清除",
                    "22": "旋转电机使能",
                    "23": "旋转电机报警清除",
                    "24": "铡刀电机使能",
                    "25": "铡刀电机报警清除",
                    "26": "横梁电机使能",
                    "27": "横梁点解报警清除",
                }
                self.insert_data(self.smallCutterIOInfo, data)

            self.recipeParamsFromEapTable = "recipeParamsFromEap"
            if self.recipeParamsFromEapTable not in collist:
                data = {
                    "key": "1",
                    "recipeName": "recipeTest",
                    "width": 0,
                    "height": 0,
                    "cropperThick": 0,
                    "jointNumber": "2",
                    "isBroken": "否"
                }
                self.insert_data(self.recipeParamsFromEapTable, data)
            self.camIPConnect = "camIPConnect"
            if self.camIPConnect not in collist:
                data = {
                    "key": "1",
                    "cam1": {
                        "cameraIP": "192.169.0.11",
                        "netIP": "192.169.0.2"
                    },
                    "cam2": {
                        "cameraIP": "192.170.0.11",
                        "netIP": "192.170.0.2"
                    },
                    "cam3": {
                        "cameraIP": "192.169.2.30",
                        "netIP": "192.169.2.2"
                    },
                    "cutCam1": {
                        "cameraIP": "192.168.0.21",
                        "netIP": "192.168.0.2"
                    },
                    "cutCam2": {
                        "cameraIP": "192.168.0.22",
                        "netIP": "192.168.0.2"
                    },
                    "cutCam3": {
                        "cameraIP": "192.168.0.23",
                        "netIP": "192.168.0.2"
                    },
                    "cutCam4": {
                        "cameraIP": "192.168.0.24",
                        "netIP": "192.168.0.2"
                    },
                }
                self.insert_data(self.camIPConnect, data)

    def insert_data(self, tableName, data):
        """
        传入的数据的数据类型可能是列表,如果是列表,列表里面的每一项都是字典,则认为是插入多条记录,否则就认为是插入一条记录
        :param tableName:表名
        :param data:插入的数据
        :return:
        """
        try:
            if isinstance(data, list) and len(data) > 0 and isinstance(data[0], dict):
                self.paramsDb[tableName].insert_many(data)
            elif isinstance(data, dict):
                self.paramsDb[tableName].insert_one(data)
            else:
                return "error", "in DbHandler.insert_data() 插入的数据类型错误,请传入字典,或者是字典的列表"
        except Exception as e:
            errorInfo = "in DbHandler.insert_data() error : {}".format(str(e))
            print(errorInfo)
            self.logger.debug(errorInfo)
            return "error", errorInfo
        return "ok", ""

    def update_data(self, tableName, query, newValues, updateOne=False):
        """
        更新数据,根据query筛选条件去更新数据
        :param tableName: 表名
        :param query: 筛选条件
        :param newValues: 新的值
        :param updateOne: 是否只更新一条的标志位
        :return:1. 成功返回 "ok",空串  2. 失败返回 "error","失败原因"
        """
        try:
            if updateOne:
                self.paramsDb[tableName].update_one(query, newValues)
            else:
                self.paramsDb[tableName].update_many(query, newValues)
        except Exception as e:
            errorInfo = "in DbHandler.update_data(),error : {}".format(str(e))
            print(errorInfo)
            self.logger.debug(errorInfo)
            return "error", errorInfo
        return "ok", ""

    def delete_data(self, tableName, query, deleteOne=False):
        """
        删除数据库,根据数据库的表名删除指定数据库的指定条件的内容
        :param tableName: 表名
        :param query: 删除条件
        :param deleteOne: 是否只删除一条
        :return:1.成功返回"ok"和空串 2.失败返回error,失败原因
        """
        try:
            if deleteOne:
                self.paramsDb[tableName].delete_one(query)
            else:
                self.paramsDb[tableName].delete_many(query)
            return "ok", ""
        except Exception as e:
            errorInfo = "in DbHandler.delete_data(),error : {}".format(str(e))
            print(errorInfo)
            self.logger.debug(errorInfo)
            return "error", errorInfo

    def delete_table(self, tableName):
        try:
            self.paramsDb.drop_collection(tableName)
        except Exception as e:
            errorInfo = "in DbHandler.delete_table(),error: {}".format(str(e))
            print(errorInfo)
            self.logger.debug(errorInfo)
            return "error", errorInfo

    def get_data_list(self, tableName, query=None, projection=None, sort="", direction=1):
        """
        根据数据库的表名,以及查询条件,获取这个数据库表中的所有的数据
        :param tableName:数据库表名
        :param query:查询条件
        :param projection:过滤条件
        :param sort:排序
        :param direction:方向
        :return: 1. 成功返回"ok",查找到的数据列表,如果查找的数据列表是空   2. 失败返回"error",以及失败原因
        """
        try:
            if query is None:
                query = {}
            if projection is None:
                projection = {
                    "_id": 0,
                    "time": 0
                }
            if sort == "":
                findData = list(self.paramsDb[tableName].find(query, projection))
            else:
                findData = list(self.paramsDb[tableName].find(query, projection).sort(sort, direction))
        except Exception as e:
            errorInfo = "in DbHandler.get_data(),error : {}".format(str(e))
            print(errorInfo)
            self.logger.debug(errorInfo)
            return "error", errorInfo
        if len(findData) == 0:
            return "error", "数据表 {} 查找到的数据是空".format(tableName)
        else:
            return "ok", findData

    def get_data_one(self, tableName, query=None, projection=None, sort="", direction=1):
        """
         根据数据库的表名,以及查询条件,获取这个数据库表中的一条数据,一般这个情况数据库中也只有唯一的一条数据
        :param tableName:数据库表名
        :param query:查询条件
        :param projection:过滤条件
        :param sort:排序
        :param direction:方向
        :return: 1. 成功返回"ok",查找到的数据列表,如果查找的数据列表是空   2. 失败返回"error",以及失败原因
        :param tableName:
        :param query:
        :param projection:
        :param sort:
        :param direction:
        :return:
        """
        try:
            if query is None:
                query = {}
            if projection is None:
                projection = {
                    "_id": 0,
                    "time": 0
                }
            if sort == "":
                findData = list(self.paramsDb[tableName].find(query, projection))
            else:
                findData = list(self.paramsDb[tableName].find(query, projection).sort(sort, direction))
        except Exception as e:
            errorInfo = "in DbHandler.get_data(),error : {}".format(str(e))
            print(errorInfo)
            self.logger.debug(errorInfo)
            return "error", errorInfo
        if len(findData) == 0:
            return "error", "数据表 {} 查找到的数据是空".format(tableName)
        else:
            return "ok", findData[0]

    def update_login_state(self, isLogin):
        """
        更新用户的登陆状态
        :param isLogin:是否是登陆状态.
        :return:
        """
        tableName = "workingInfo"
        query = {
            "key": "1"
        }
        newValues = {
            "$set": {
                "loginSuccess": isLogin
            }
        }
        return self.update_data(tableName, query, newValues)

    def get_login_state(self):
        """
        获取用户的登陆状态
        :return: 登陆成功返回True,失败返回False
        """
        tableName = "workingInfo"
        query = {
            "key": "1"
        }
        res, data = self.get_data_one(tableName, query)
        if res == "ok":
            return data.get("loginSuccess", False)
        else:
            errorInfo = "in DbHandler.get_login_state() error : {}".format(data)
            print(errorInfo)
            self.logger.debug(errorInfo)
            return False

    def get_cam_zmc_params(self, tableName):
        """
        获取拍照控制器的参数列表,只获取一条数据
        :param tableName: 拍照控制器的表名
        :return:
        """
        query = {
            "key": "1"
        }
        return self.get_data_one(tableName, query)

    def get_cbj_zmc_params(self, tableName):
        """
        获取裁切机的参数列表,只获取一条数据
        :param tableName: 数据库表名
        :return:
        """
        query = {
            "key": "1"
        }
        return self.get_data_one(tableName, query)

    def get_cutter_zmc_params(self, tableName):
        """
        获取铡刀控制器的参数列表,只获取一条数据
        :param tableName: 数据库表名
        :return:
        """
        query = {
            "key": "1"
        }
        return self.get_data_one(tableName, query)

    def get_light_params_big(self, lightNumber):
        """
        获取第一个灯管的参数信息
        :return:
        """
        if lightNumber > 5:
            return "error", "灯管编号超过限制,灯管编号最大支持到4"
        tableNameList = [self.light1ParamsTalbeBig, self.light2ParamsTableBig, self.light3ParamsTableBig, self.light4ParamsTableBig]
        tableName = tableNameList[lightNumber - 1]
        query = {
            "key": "1"
        }
        return self.get_data_one(tableName, query)

    def get_light_params_small(self, lightNumber):
        """
        获取第一个灯管的参数信息
        :return:
        """
        if lightNumber > 5:
            return "error", "灯管编号超过限制,灯管编号最大支持到4"
        tableNameList = [self.light1ParamsTalbeSmall, self.light2ParamsTalbeSmall, self.light3ParamsTalbeSmall, self.light4ParamsTalbeSmall]
        tableName = tableNameList[lightNumber - 1]
        query = {
            "key": "1"
        }
        return self.get_data_one(tableName, query)

    def save_light_params_big(self, lightNum, newData):
        """
        保存灯管的位置信息
        :param lightNum:灯管的编号
        :param newData: 要保存的数据
        :return:
        """
        if lightNum == 1:
            tableName = self.light1ParamsTalbeBig
        elif lightNum == 2:
            tableName = self.light2ParamsTableBig
        elif lightNum == 3:
            tableName = self.light3ParamsTableBig
        else:
            tableName = self.light4ParamsTableBig

        query = {
            "key": "1"
        }
        newValues = {
            "$set": newData
        }
        return self.update_data(tableName, query, newValues)

    def save_light_params_small(self, lightNum, newData):
        """
        保存灯管的位置信息
        :param lightNum:灯管的编号
        :param newData: 要保存的数据
        :return:
        """
        if lightNum == 1:
            tableName = self.light1ParamsTalbeSmall
        elif lightNum == 2:
            tableName = self.light2ParamsTalbeSmall
        elif lightNum == 3:
            tableName = self.light3ParamsTalbeSmall
        else:
            tableName = self.light4ParamsTalbeSmall

        query = {
            "key": "1"
        }
        newValues = {
            "$set": newData
        }
        return self.update_data(tableName, query, newValues)

    def web_request_get_user_info(self):
        """
        前端界面获取所有用户的账号信息
        :return:
        """
        tableName = "userinfo"
        if tableName not in self.paramsDb.list_collection_names():
            return []
        else:
            res, userInfo = self.get_data_list(tableName)
            return userInfo if res == "ok" else []

    def web_request_save_user_info(self, userInfo):
        """
        前端界面保存用户信息
        :param userInfo:
        :return:
        """
        tableName = "userinfo"
        key = userInfo['key']
        query = {
            "key": key
        }
        queryName = {
            "username": userInfo["username"]
        }
        self.delete_data(tableName, queryName)  # 删除同名的用户账号,用户名会覆盖掉
        if userInfo["username"] == "admin":
            return "保存失败,用户名不能是admin!"
        res, data = self.get_data_one(tableName, query)
        if res != "ok":
            userInfo["registerTime"] = get_time_now_string()
            return self.insert_data(tableName, userInfo)[0]
        else:
            newValues = {
                "$set": userInfo
            }
            return self.update_data(tableName, query, newValues)[0]

    def web_request_delete_user_info(self, delKey):
        """
        前端界面点击了删除用户信息的按钮,按照key值去删除
        :param delKey: 要删除的用户信息的key值
        :return:
        """
        tableName = "userinfo"
        query = {
            "key": delKey
        }
        res, info = self.delete_data(tableName, query)
        return res if res == "ok" else info

    def get_user_list_by_username(self, username):
        """
        根据用户名获取userinfo列表
        :param username: 用户名
        :return:成功返回列表,失败返回空列表
        """
        tableName = "userinfo"
        query = {
            "username": username
        }
        res, data = self.get_data_one(tableName, query)
        return data if res == "ok" else []

    def get_order_by_key(self, orderUsedKey):
        """
        根据key值,获取工单数据
        :param orderUsedKey:
        :return:
        """
        tableName = "order"
        query = {
            "key": orderUsedKey
        }
        res, orderDict = self.get_data_one(tableName, query)
        return orderDict if res == "ok" else {}

    def web_request_get_order_by_key(self, orderUsedKey):
        """
        前端界面请求刷新工单数据
        :param orderUsedKey:
        :return:
        """
        tableName = "order"
        query = {
            "key": orderUsedKey
        }
        totalOrders = self.get_total_orders()
        res, workingOrder = self.get_data_one(tableName, query)
        if res != "ok":
            workingOrder = totalOrders[0]
        return totalOrders, [workingOrder]

    def web_request_search_order(self, orderId):
        """
        前端界面请求搜索工单
        :param orderId: 搜索的工单id号
        :return:
        """
        tableName = "order"
        query = {
            "id": orderId
        }
        totalOrders = self.get_total_orders()
        res, searchOrder = self.get_data_list(tableName, query)
        if res != "ok":
            searchOrder = []
        return totalOrders, searchOrder

    def save_order_used_key(self, workingKey):
        """
        保存正在作业的workingKey的值
        :param workingKey: 当前正在作业的工单key值
        :return:
        """
        query = {
            "key": "1"
        }
        newValues = {
            "$set": {
                "orderUsedKey": workingKey
            }
        }
        self.update_data(self.workingInfoTable, query, newValues)

    def get_working_used_key(self):
        """
        获取当前工作的key值.
        :return:
        """
        tableName = "workingInfo"
        query = {
            "key": "1"
        }
        res, data = self.get_data_one(tableName, query)
        if res == "ok":
            workingKey = data.get("orderUsedKey", None)
            if workingKey is None:
                oneOrder = self.get_total_orders()[0]
                workingKey = oneOrder.get("key", 0)
                newValues = {
                    "$set": {
                        "orderUsedKey": workingKey
                    }
                }
                self.update_data(tableName, query, newValues)
            return workingKey

    def get_total_orders(self):
        tableName = "order"
        query = {}
        res, data = self.get_data_list(tableName, query)
        if res != "ok":
            # 插入一个工单
            data = {
                "key": 1,
                "width": 600,
                "height": 600,
                "isFirstTime": False,
                "jointNumber": "2",
                "isBroken": "否"
            }
            self.insert_data(tableName, data)
            data = [data]
        return data

    def get_working_info(self):
        """
        获取wokinginfo数据表的内容
        :return:
        """
        tableName = self.workingInfoTable
        query = {
            "key": "1"
        }
        return self.get_data_one(tableName, query)

    def get_main_alarm_info(self):
        """
        获取mainAlarminfo数据表的内容
        :return:
        """
        query = {
            "key": "1"
        }
        return self.get_data_one(self.mainAlarmInfoTable, query)

    def get_main_alarm_info_US(self):
        """
        获取mainAlarminfo数据表的内容
        :return:
        """
        query = {
            "key": "1"
        }
        return self.get_data_one(self.mainAlarmInfoUSTable, query)

    def get_IO_info(self, table):
        """
        获取mainAlarminfo数据表的内容
        :return:
        """
        query = {
            "key": 1
        }
        return self.get_data_one(table, query)

    def web_request_get_working_info(self):
        """
        前端界面获取wokinginfo数据库的数据
        :return:
        """
        res, data = self.get_working_info()
        return [data] if res == "ok" else []

    def update_order(self, key, newData):
        """
        根据key值更新工单的信息
        :param key 要更新的工单的key值
        :param newData:新的值
        :return:
        """
        query = {
            "key": key
        }
        newValues = {
            "$set": newData
        }
        return self.update_data(self.orderTable, query, newValues)

    def web_request_save_order(self, newOrder):
        """
        界面上点击了保存工单.
        :param newOrder:
        :return:
        """
        # 分两种情况,工单已经存在,或者工单不存在
        tableName = "order"
        newKey = newOrder["key"]
        query = {
            "key": newKey,
        }
        res, data = self.get_data_one(tableName, query)
        if res == "ok":
            oldWidth = data.get("width", 0)
            oldHeight = data.get("height", 0)
            newWidth = newOrder.get("width", 0)
            newHeight = newOrder.get("height", 0)
            if oldWidth != newWidth or oldHeight != newHeight:
                newOrder["firstCheckWidth"] = 0
                newOrder["firstCheckHeight"] = 0
            newValues = {
                "$set": newOrder
            }
            self.update_data(tableName, query, newValues)
        else:
            self.insert_data(tableName, newOrder)

        return self.web_request_get_order_by_key(newKey)

    def web_request_delete_order(self, delKey):
        """
        前端界面请求删除工单
        :param delKey: 要删除的工单key值
        :return:
        """
        tableName = "order"
        query = {
            "key": delKey
        }
        workingKey = self.get_working_used_key()
        self.delete_data(tableName, query)
        return self.web_request_get_order_by_key(workingKey)

    def get_cut_speed_by_cropper_thick(self, cropperThick):
        """
        根据铜箔的宽度,获取切割的速度
        :param cropperThick: 铜箔的宽度
        :return:
        """
        cropperThick = str(cropperThick)
        if "0.33" in cropperThick:
            keyName = "speedLev1"
        elif "0.34" in cropperThick:
            keyName = "speedLev2"
        elif "1.5" in cropperThick:
            keyName = "speedLev3"
        elif "1.6" in cropperThick:
            keyName = "speedLev4"
        else:
            keyName = "speedLev5"

        res, speedData = self.get_knife_cut_params()
        if res != "ok":
            return 800, 800
        cutSpeed = speedData.get(keyName)
        firstCutSpeed = int(float(speedData.get("firstCutRate")) * cutSpeed)
        return (800, 800) if cutSpeed is None else (firstCutSpeed, cutSpeed)

    def get_line_cam_check_thres(self):
        """
        获取线阵相机的识别阈值
        :return:
        """
        tableName = self.lineCamCheckThres
        query = {
            "key": "1"
        }
        return self.get_data_one(tableName, query)

    def save_line_cam_check_thres(self, newData):
        """
        保存线阵相机的识别阈值
        :param newData: 新的值
        :return:
        """
        tableName = self.lineCamCheckThres
        query = {
            "key": "1"
        }
        newValues = {
            "$set": newData
        }
        return self.update_data(tableName, query, newValues)

    def get_big_cutter_cam_check_thres(self):
        """
        获取铡刀相机的识别阈值
        :return:
        """
        tableName = self.cutterCamCheckThresBig
        query = {
            "key": "1"
        }
        return self.get_data_one(tableName, query)

    def get_small_cutter_cam_check_thres(self):
        """
        获取铡刀相机的识别阈值
        :return:
        """
        tableName = self.cutterCamCheckThresSmall
        query = {
            "key": "1"
        }
        return self.get_data_one(tableName, query)

    def save_config_params(self, newData):
        """
        保存线阵相机的全局参数设置的值
        :param newData:
        :return:
        """
        tableName = self.configParamsTable
        query = {
            "key": "1"
        }
        newValues = {
            "$set": newData
        }
        return self.update_data(tableName, query, newValues)

    def save_big_cutter_cam_check_thres(self, newData):
        """
        保存面阵相机的识别阈值
        :param newData: 新的值
        :return:
        """
        tableName = self.cutterCamCheckThresBig
        query = {
            "key": "1"
        }
        newValues = {
            "$set": newData
        }
        return self.update_data(tableName, query, newValues)

    def save_small_cutter_cam_check_thres(self, newData):
        """
        保存面阵相机的识别阈值
        :param newData: 新的值
        :return:
        """
        tableName = self.cutterCamCheckThresSmall
        query = {
            "key": "1"
        }
        newValues = {
            "$set": newData
        }
        return self.update_data(tableName, query, newValues)

    def get_knife_cut_params(self):
        """
        获取切割的时候用到的参数
        :return:
        """
        tableName = self.knifeCutParams
        query = {
            "key": "1"
        }
        return self.get_data_one(tableName, query)

    def save_knife_cut_params(self, newData):
        """
        保存刀的切割相关参数
        :param newData: 新的值
        :return:
        """
        tableName = self.knifeCutParams
        query = {
            "key": "1"
        }
        newValues = {
            "$set": newData
        }
        return self.update_data(tableName, query, newValues)

    def save_trans_mtx_data(self, newData):
        """
        保存标定的参数的相关值.
        :param newData:新的标定值
        :return:
        """
        tableName = self.transMtxTable
        query = {
            "key": "1"
        }
        newValues = {
            "$set": newData
        }
        return self.update_data(tableName, query, newValues)

    def get_trans_mtx_data(self):
        """
        获取transMtx表的内容数据
        :return:
        """
        tableName = self.transMtxTable
        query = {
            "key": "1"
        }
        return self.get_data_one(tableName, query)

    def get_capfile_data(self):
        """
        获取capfileData数据表的内容
        :return:
        """
        tableName = self.capfileTable
        query = {
            "key": "1"
        }
        return self.get_data_one(tableName, query)

    def get_image_joint_params(self):
        """
        获取image_joint_params的数据表内容
        :return:
        """
        tableName = self.imageJointParamsTable
        query = {
            "key": "1"
        }
        return self.get_data_one(tableName, query)

    def save_image_joint_params(self, newData):
        """
        保存image_joint_params的数据
        :return:
        """
        query = {
            "key": "1"
        }
        tableName = self.imageJointParamsTable
        newValues = {
            "$set": newData
        }

        return self.update_data(tableName, query, newValues)

    def web_request_get_image_joint_params(self):
        """
        前端界面请求获取拼接参数的列表
        :return:
        """
        res, imageJointParams = self.get_image_joint_params()
        return [imageJointParams] if res == "ok" else []

    def web_request_get_config_params(self):
        """
        前端界面请求获取全局相机的参数列表
        :return:
        """
        query = {
            "key": "1"
        }
        res, configParams = self.get_data_one(self.configParamsTable, query)
        return [configParams] if res == "ok" else []

    def save_eap_config_params(self, newData):
        """
        保存eap_config_table表的数据
        @param newData:
        @return:
        """
        query = {
            "key": "1"
        }
        newValues = {
            "$set": newData
        }
        return self.update_data(self.eap_config_params, query, newValues)

    def save_working_info_data(self, newData):
        """
        保存workingInfo的数据
        :param newData: 新的值
        :return:
        """
        query = {
            "key": "1"
        }
        newValues = {
            "$set": newData
        }
        return self.update_data(self.workingInfoTable, query, newValues)

    def web_reqeust_save_working_info(self, newData):
        """
        前端界面点击了保存作业信息的逻辑
        :param newData: 新的数据
        :return:
        """
        return self.save_working_info_data(newData)

    def get_produce_record_table_data(self):
        """
        获取produceRecordTale的数据表的结果.
        :return:
        """
        query = {
            "key": "1"
        }
        return self.get_data_one(self.produceAmountRecordTable, query)

    def update_produce_record(self, boardNumbers):
        """
        更新产量记录里面的值,月份和日期都要来一遍
        :param boardNumbers: 增加的板的数量.
        :return:
        """
        # 先获取produceAmount数据
        res, data = self.get_produce_record_table_data()
        if res != "ok":
            return "error", data
        nowYear = datetime.datetime.now().year
        recordYear = data.get("recordYear")
        if nowYear != recordYear:  # 如果记录的年份变了,数据就要重新清零
            self.delete_table(self.produceAmountRecordTable)
            newData = {
                "key": "1",
                "recordYear": datetime.datetime.now().year,
                "1": 0,
                "2": 0,
                "3": 0,
                "4": 0,
                "5": 0,
                "6": 0,
                "7": 0,
                "8": 0,
                "9": 0,
                "10": 0,
                "11": 0,
                "12": 0,
                "dayAmount": {

                }
            }
            self.insert_data(self.produceAmountRecordTable, newData)

            res, data = self.get_produce_record_table_data()
            if res != "ok":
                return "error", data
        monthKey = str(datetime.datetime.now().month)
        dateKey = get_time_now_string()[5:10]
        print("monthKey = {},dateKey = {}".format(monthKey, dateKey))
        oldMonthVal = data.get(monthKey, 0)
        oldDayAmountDict = data.get("dayAmount", {})
        oldDayVal = oldDayAmountDict.get(dateKey, 0)
        newMonthVal = oldMonthVal + boardNumbers
        newDateVal = oldDayVal + boardNumbers
        oldDayAmountDict[dateKey] = newDateVal

        query = {
            "key": "1"
        }
        newData = {
            monthKey: newMonthVal,
            "dayAmount": oldDayAmountDict,
        }
        newValues = {
            "$set": newData,
        }
        return self.update_data(self.produceAmountRecordTable, query, newValues)

    @staticmethod
    def web_request_dump_data_base():
        """
        界面上点击了备份数据库,进行数据库的备份工作
        :return:
        """
        return dump_data()

    @staticmethod
    def web_request_import_data_base():
        """
        界面上点击了导入数据库,进行数据库的导入工作
        :return:
        """
        return import_data()

    @staticmethod
    def web_request_open_database_dump_dir():
        """
        界面上点击了打开备份目录
        :return:
        """
        return open_database_dump_dir()

    @staticmethod
    def web_request_open_databaes_import_dir():
        """
        界面上点击了打开导入目录
        :return:
        """
        return open_database_import_dir()

    def web_request_get_main_alarm_info_table(self):
        """
        界面上点击获取报警信息表的按钮
        :return:
        """
        res, data = self.get_main_alarm_info()
        if res != "ok":
            return data
        alarmDict = data.get("mainAlarmInfo")
        newAlarmTableVal = []
        tableDataIndex1 = "bitPos"
        tableDataIndex2 = "alarmText"
        alarmDictKey = alarmDict.keys()
        newAlarmKey = sorted(alarmDictKey, key=lambda x: int(x))
        newAlarmDict = {key: alarmDict[key] for key in newAlarmKey}  # 将原来的字典按照键进行排序,组合新字典返回

        for key, val in newAlarmDict.items():
            newVal = {
                "key": key,  # table空间里面的值必须要有一个key值,不然控件那里容易报错.
                tableDataIndex1: key,
                tableDataIndex2: val
            }
            newAlarmTableVal.append(newVal)
        return newAlarmTableVal

    def web_request_save_main_alarm_info(self, newAlarmDict):
        """
        保存报警信息,将报警信息重新保存一下.有可能是覆盖,也有可能是更改,先将原来的字典获取到.
        :return:
        """
        res, data = self.get_main_alarm_info()
        if res != "ok":
            return data
        alarmDict = data.get("mainAlarmInfo")
        alarmKey, alarmInfoText = newAlarmDict
        if alarmInfoText == "删除":
            if str(alarmKey) in alarmDict.keys():
                del alarmDict[alarmKey]
        else:
            alarmDict[str(alarmKey)] = str(alarmInfoText)
        newValues = {
            "$set": {
                "mainAlarmInfo": alarmDict
            }
        }
        query = {
            "key": "1"
        }
        res, info = self.update_data(self.mainAlarmInfoTable, query, newValues)
        if res != "ok":
            return info
        return "ok"

    def get_eap_user_info(self):
        """
        获取eap的登录的用户信息
        @return:
        """
        query = {
            "key": "1"
        }
        return self.get_data_one(self.eap_user_table, query)

    def update_eap_uer_info(self, new_data):
        """
        更新eap的登录的用户信息
        @param new_data:
        @return:
        """
        query = {
            "key": "1"
        }
        newValues = {
            "$set": new_data
        }
        return self.update_data(self.eap_user_table, query, newValues)

    def get_eap_config_params(self):
        """
        获取和eap通信的参数表
        :return:
        """
        query = {
            "key": "1"
        }
        return self.get_data_one(self.eap_config_params, query)

    def get_eap_recipe_params(self):
        """
        获取eap下发的参数表
        :return:
        """
        query = {
            "key": "1"
        }
        return self.get_data_one(self.recipeParamsFromEapTable, query)

    def get_device_state_to_eap(self):
        """
        获取发送给eap的设备状态表格内容
        :return:
        """
        query = {
            "key": "1"
        }
        return self.get_data_one(self.deviceStateToEapTable, query)

    def get_calc_args_from_txt(self, calcArgs):
        """
        获取算子参数的列表
        :param calcArgs:
        :return:
        """
        retDict = {}
        for args in calcArgs:
            key = args.split(":")[0]
            gaussianList = args.split(":")[1].split("_")
            arg1 = args.split(":")[2]
            arg2 = args.split(":")[3]
            arg3 = args.split(":")[4]
            arg4 = args.split(":")[5]
            thresList = args.split(":")[6].split("_")
            arg5 = args.split(":")[7]

            # 转换成int或者float类型
            gaussianList = [int(x) for x in gaussianList]
            arg1 = int(arg1)
            arg2 = int(arg2)
            arg3 = int(arg3)
            arg4 = int(arg4)
            arg5 = float(arg5)
            thresList = [int(x) for x in thresList]

            value = [gaussianList, arg1, arg2, arg3, arg4, thresList, arg5]
            retDict[key] = value
        return retDict

    def get_alarm_info_to_eap(self):
        """
        获取发送给eap的报警信息表内容
        :return:
        """
        query = {
            "key": "1"
        }
        return self.get_data_one(self.alarmReportToEapTable, query)

    def web_request_update_calc_args(self):
        """
        更新算子
        :return:
        """
        try:
            if not os.path.exists(CALC_ARGS_TXT_PATH):
                return "要更新的算子文件不存在,请确保算子文件在当前运行的项目的根目录下!"
            calcArgs = []
            with open(CALC_ARGS_TXT_PATH) as f:
                while True:
                    data = f.readline()
                    dataLength = len(data)
                    if dataLength <= 10:
                        break
                    calcArgs.append(data)
            # 根据读到的算子文件,获取到字典.
            if len(calcArgs) == 0:
                return "calcArgs.txt的内容是空的,请找软件开发要正确的算子文件进行更新"
            calcArgsNew = self.get_calc_args_from_txt(calcArgs)
            newData = {
                "calcArgsZj01": calcArgsNew
            }
            res, info = self.save_config_params(newData)
            return "ok" if res == "ok" else info
        except Exception as e:
            errorInfo = "in web_request_update_calc_args() error: {}".format(str(e))
            print(errorInfo)
            self.logger.debug(errorInfo)

    def get_usernames(self):
        try:
            userinfo = list(self.get_data_list('userinfo')[1])
            if len(userinfo) != 0:
                usernames = []
                for i in userinfo:
                    usernames.append(i.get('username'))
                usernames.append('admin')
                return 'ok', usernames
            else:
                return 'error', ['请使用管理员账号登录，或者请联系管理员创建用户账号！']
        except Exception as e:
            return "error", str(e)

    def get_tableUsedDays(self):
        """
        获取台布使用时长
        """
        ret, data = self.get_working_info()
        otherStyleTime = data.get("tableUsedInit")
        ymd = otherStyleTime.split(" ")[0]
        HMS = otherStyleTime.split(" ")[1]
        Y = ymd.split("-")[0]
        m = ymd.split("-")[1]
        d = ymd.split("-")[2]
        H = HMS.split(":")[0]
        M = HMS.split(":")[1]
        S = HMS.split(":")[2]
        a_y = time.strftime("%Y", time.localtime())
        a_m = time.strftime("%m", time.localtime())
        a_d = time.strftime("%d", time.localtime())
        a_H = time.strftime("%H", time.localtime())
        a_M = time.strftime("%M", time.localtime())
        a_S = time.strftime("%S", time.localtime())
        d1 = datetime.datetime(int(Y), int(m), int(d), int(H), int(M), int(S))
        d2 = datetime.datetime(int(a_y), int(a_m), int(a_d), int(a_H), int(a_M), int(a_S))
        interval = d2 - d1
        print(interval.days, interval.seconds // 60 / 60 / 24)
        tableUsed = round(float(interval.days) + float(interval.seconds / 60 / 60 / 24), 2)
        return tableUsed

    def get_cam_IP_connect(self):
        """
        获取网口网段和相机IP
        :return:
        """
        tableName = self.camIPConnect
        query = {
            "key": "1"
        }
        return self.get_data_one(tableName, query)

    def get_cam_IP_connect_by_camName(self):
        res, IP_data = self.get_cam_IP_connect()
        line_cam1 = [IP_data.get('cam1').get('cameraIP'), IP_data.get('cam1').get('netIP')]
        line_cam2 = [IP_data.get('cam2').get('cameraIP'), IP_data.get('cam2').get('netIP')]
        line_cam3 = [IP_data.get('cam3').get('cameraIP'), IP_data.get('cam3').get('netIP')]
        cutCam1 = [IP_data.get('cutCam1').get('cameraIP'), IP_data.get('cutCam1').get('netIP')]
        cutCam2 = [IP_data.get('cutCam2').get('cameraIP'), IP_data.get('cutCam2').get('netIP')]
        cutCam3 = [IP_data.get('cutCam3').get('cameraIP'), IP_data.get('cutCam3').get('netIP')]
        cutCam4 = [IP_data.get('cutCam4').get('cameraIP'), IP_data.get('cutCam4').get('netIP')]
        return line_cam1, line_cam2, line_cam3, cutCam1, cutCam2, cutCam3, cutCam4

    def save_cam_IP_connect_info_data(self, newData):
        """
        保存workingInfo的数据
        :param newData: 新的值
        :return:
        """
        query = {
            "key": "1"
        }
        newValues = {
            "$set": newData
        }
        return self.update_data(self.camIPConnect, query, newValues)

    def web_request_save_cam_IP_connect_info_data(self, newData):
        """
        保存workingInfo的数据
        :param newData: 新的值
        :return:
        """
        query = {
            "key": "1"
        }
        data = {
            "cam1": {
                "cameraIP": newData.get('cam1_Ip'),
                "netIP": newData.get('cam1_Mbps'),
            },
            "cam2": {
                "cameraIP": newData.get('cam2_Ip'),
                "netIP": newData.get('cam2_Mbps'),
            },
            "cam3": {
                "cameraIP": newData.get('cam3_Ip'),
                "netIP": newData.get('cam3_Mbps'),
            },
            "cutCam1": {
                "cameraIP": newData.get('cutcam1_Ip'),
                "netIP": newData.get('cutcam1_Mbps'),
            },
            "cutCam2": {
                "cameraIP": newData.get('cutcam2_Ip'),
                "netIP": newData.get('cutcam1_Mbps'),
            },
            "cutCam3": {
                "cameraIP": newData.get('cutcam3_Ip'),
                "netIP": newData.get('cutcam1_Mbps'),
            },
            "cutCam4": {
                "cameraIP": newData.get('cutcam4_Ip'),
                "netIP": newData.get('cutcam1_Mbps'),
            }
        }
        newValues = {
            "$set": data
        }
        return self.update_data(self.camIPConnect, query, newValues)

    def insert_production_download(self, data):
        return self.insert_data(self.eapProdDownloadTable, data)

    def get_production_download_info_data(self):
        return self.get_data_list(self.eapProdDownloadTable, sort="key", direction=1)

    def delete_download_info(self, query):
        return self.delete_data(self.eapProdDownloadTable, query)

    def update_download_info(self, query, newData):
        newValues = {
            "$set": newData
        }
        return self.update_data(self.eapProdDownloadTable, query, newValues)

    def insert_lot_command_download(self, data):
        return self.insert_data(self.lotCommandDownloadTable, data)

    def delete_lot_command_download(self, query):
        return self.delete_data(self.lotCommandDownloadTable, query=query)

    def get_lot_command_download_info(self):
        return self.get_data_list(self.lotCommandDownloadTable, sort="key")

    def insert_cim_message(self, data):
        # 时间从大到小排序,最新的显示在最前面
        res, tableData = self.get_data_list(self.cimMessageTable, sort="key", direction=-1)
        if res == "ok":
            # 如果数据表里面没有数据,先判断数据的个数,如果已经是>=10个,就将后面的删除掉
            if len(tableData) >= 10:
                # 如果只保留9个数据,将后面的数据删除掉
                for deleteData in tableData[9:]:
                    query = {
                        "key": deleteData.get("key")
                    }
                    self.delete_data(self.cimMessageTable, query)

        return self.insert_data(self.cimMessageTable, data)

    def get_cim_message(self):
        """
        获取cimMessage数据表的内容
        :return:
        """
        res, tableData = self.get_data_list(self.cimMessageTable, sort="key", direction=-1)
        if res == "ok":
            return tableData
        else:
            return []

    def update_all_orders_with_new_fields(self):
        """
        遍历order表，为每个订单添加新字段：
        - prod_id: 使用原id字段的值
        - lot_id: 设置为"1"
        - planCount: 设置为100
        - finished: 设置为0
        :return: 更新结果
        """
        try:
            # 获取所有订单数据
            res, orders = self.get_data_list(self.orderTable)
            if res != "ok":
                return "error", f"获取订单数据失败: {orders}"
            
            updated_count = 0
            error_count = 0
            
            for order in orders:
                try:
                    # 获取原id字段的值作为prod_id
                    original_id = order.get("id", "")
                    
                    # 构建更新数据
                    new_data = {
                        "prod_id": original_id,
                        "lot_id": "1",
                        "planCount": 100,
                        "finished": 0
                    }
                    
                    # 更新订单
                    query = {"key": order.get("key")}
                    new_values = {"$set": new_data}
                    
                    update_res, update_info = self.update_data(self.orderTable, query, new_values)
                    if update_res == "ok":
                        updated_count += 1
                        print(f"成功更新订单 key={order.get('key')}, id={original_id}")
                    else:
                        error_count += 1
                        print(f"更新订单失败 key={order.get('key')}: {update_info}")
                        
                except Exception as e:
                    error_count += 1
                    print(f"处理订单时出错 key={order.get('key')}: {str(e)}")
            
            return "ok", f"更新完成: 成功{updated_count}条, 失败{error_count}条"
            
        except Exception as e:
            error_info = f"批量更新订单失败: {str(e)}"
            print(error_info)
            self.logger.debug(error_info)
            return "error", error_info

if __name__ == '__main__':
    logger = None
    db = DbHandler()
    key = int(time.time() * 1000)
    res, alarmInfo = db.get_main_alarm_info_US()
    print(alarmInfo.get(""))

    data = {
        "key": key,
        "lot_id": "test",
        "prod_id": "123"
    }
    db.insert_lot_command_download(data)

    # db = DbHandler()
    # import_data()
